﻿#define _CRT_SECURE_NO_WARNINGS 1

#include <iostream>
#include <vector>
#include <thread>
#include <mutex>


//int x = 0;
//std::mutex m;
//
//void func(int a)
//{
//	m.lock();
//	for (int i = 0; i < a; i++)
//	{
//		x++;
//	}
//	m.unlock();
//}
//
//int main()
//{
//	std::thread t1(func, 100000);
//	std::thread t2(func, 200000);
//
//	t1.join();
//	t2.join();
//
//	std::cout << "x = " << x << std::endl;
//
//	return 0;
//}



//void func(int a, int& rx, std::mutex& rm)
//{
//	rm.lock();
//	for (int i = 0; i < a; i++)
//	{
//		rx++;
//	}
//	rm.unlock();
//}

//int main()
//{
//	int x = 0;
//	std::mutex m;
//
//	auto func = [&](int n)
//	{
//		m.lock();
//		for (int i = 0; i < n; i++)
//		{
//			x++;
//		}
//		m.unlock();
//	};
//
//	std::thread t1(func, 100000);
//	std::thread t2(func, 200000);
//
//	t1.join();
//	t2.join();
//	std::cout << "x = " << x << std::endl;
//	return 0;
//}


//int main()
//{
//	int x = 0;
//	std::mutex m;
//
//	auto func = [&](int n)
//	{
//		m.lock();
//		for (int i = 0; i < n; i++)
//		{
//			x++;
//		}
//		m.unlock();
//	};
//
//	int n = 5; // 创建n个线程
//	std::vector<std::thread> vThds(n);  // 只创建线程不执行任务
//
//	for (auto& thread : vThds)
//	{
//		thread = std::thread(func, 10000);
//	}
//
//
//	for (auto& thread : vThds)
//	{
//		thread.join();
//	}
//
//	std::cout << "x = " << x << std::endl;
//	return 0;
//}



//#include <iostream>
//#include <functional> // 包含 std::bind
//
////void add(int a, int b)
////{
////    std::cout << " a = " << a << ", b = " << b << std::endl;
////    std::cout << "Sum: " << a + b << std::endl;
////}
////
////int main() {
////    // 将函数 add 的第一个参数绑定为 10
////    auto boundAdd = std::bind(add, 10, std::placeholders::_1);
////
////    // 调用 boundAdd，只需要提供第二个参数
////    boundAdd(5); // 输出: Sum: 15
////    boundAdd(20); // 输出: Sum: 30
////
////    return 0;
////}
//
//void print(int val)
//{
//    std::cout << val << std::endl;
//}
//
//int main()
//{
//    // 声明一个 std::function 对象
//    std::function<void(int)> f = print;
//    std::function<void(int)> h;
//    h = f; // 合法赋值
//
//    std::function<void(int, double)> j;
//    //j = h; // 编译错误，类型不匹配
//    j = [](int i, double) {}; // 合法，隐式转换
//    return 0;
//}



//#include <iostream>
//#include <vector>
//#include <set>
//
//class A
//{
//public:
//	int a = 1;
//	int b = 0;
//};
//
//int main()
//{
//	const A a;
//	std::set<A> s;
//	/*s.insert(a);
//	s.begin()->a = 0;*/
//
//	std::vector<A> v;
//	v.push_back(a);
//	v.begin()->a = 0;
//	return 0;
//}


//#include <iostream>  
//#include <memory>  
//#include <string>  
//
//// 基类定义（保持不变）  
//struct BaseA {
//    virtual ~BaseA() = default;
//    virtual void FuncA() {}
//    virtual void FuncB() { std::cout << "BaseA FuncB\n"; }
//};
//
//struct BaseB {
//    virtual ~BaseB() = default;
//    virtual void FuncA() {}
//    virtual void FuncC() { std::cout << "BaseB FuncC\n"; }
//};
//
//struct Derive : public BaseA, public BaseB {
//    void FuncB() override { std::cout << "Derive FuncB\n"; }
//    void FuncC() override { std::cout << "Derive FuncC\n"; }
//};
//
//// 工厂类  
//class Factory {
//public:
//    // 工厂方法，根据类型字符串创建对象  
//    static std::unique_ptr<BaseA> createObject(const std::string& type) {
//        if (type == "Derive") {
//            return std::make_unique<Derive>();
//        }
//        else {
//            // 这里可以添加更多类型的创建逻辑，或者抛出异常  
//            throw std::invalid_argument("Unknown type");
//        }
//    }
//};
//
//int main() {
//    // 使用工厂创建对象  
//    std::unique_ptr<BaseA> obj = Factory::createObject("Derive");
//
//    // 多态调用  
//    obj->FuncB(); // 输出: Derive FuncB  
//
//    // 注意：由于obj是BaseA类型的指针，不能直接调用FuncC()  
//    // 如果需要调用FuncC()，需要将其转换为正确的类型或通过其他方式获取BaseB类型的指针/引用  
//
//    // 假设我们知道实际类型是Derive，可以进行向下转型（但通常不推荐这样做，因为它破坏了多态性）  
//    if (auto derive = dynamic_cast<Derive*>(obj.get())) {
//        derive->FuncC(); // 输出: Derive FuncC  
//    }
//    else {
//        std::cout << "Failed to cast to Derive\n";
//    }
//
//    return 0;
//}


//#include<stdio.h>
//typedef void (*func)();
//
//void funcA()
//{
//	printf("FUNC_A\n");
//}
//void funcB()
//{
//	printf("FUNC_B\n");
//}
//
//
//typedef struct
//{
//	func fun;
//}base;
//
//typedef struct
//{
//	base _base;
//}deviceA;
//
//typedef struct
//{
//	base _base;
//}deviceB;
//
//void InitA(deviceA* a, func fun)
//{
//	a->_base.fun = fun;
//}
//void InitB(deviceB* b, func fun)
//{
//	b->_base.fun = fun;
//}
//int main()
//{
//	deviceA a;
//	deviceB b;
//	InitA(&a, funcA);
//	InitB(&b, funcB);
//
//	base* ptr = NULL;
//	ptr = (base*)&a;
//	ptr->fun();
//	ptr = (base*)&b;
//	ptr->fun();
//	return 0;
//}


// 第一题。fun函数能不能求出数组的长度
// 答：不能数组在传参时会退化为指针，因此str是一个char类型的指针，所以sizeof(str)求得的是指针的字节大小（8个字节或4个字节）
//int fun(char str[]) {
//    int len = sizeof(str) / sizeof(str[0]);
//    return len;
//}
//
////第二题，这段程序运行结果是什么
//// 答：会造成 1. num个字节空间的内存泄漏；2. str空指针的解引用
//// 因为str在传参给p时，是值拷贝，p变量指向堆上分配的空间，但是出了GetMemory作用域后p就会被销毁，之后就无法访问到这块空间了，
//// 导致堆上分配的空间泄漏
//// 同时，因为没有成功为str开辟空间，因此str还是NULL，在调用strcpy会对str进行解引用，造成对野指针的解引用
//#include<iostream>
//using namespace std;
//void GetMemory(char* p, int num)
//{
//    p = (char*)malloc(sizeof(char) * num);
//}

//int main()
//{
//    char* str = NULL;
//    GetMemory(str, 100);
//    strcpy(str, "hello");
//    return 0;
//}
//
//
//
//第三题 程序输出什么
//答：类成员变量初始化的顺序与初始化列表中中顺序无关，取决于类成员变量的声明的顺序
// 结果为：随机值，100

//class T {
//public:
//    int a;
//    int b;
//
//    T(int i) :b(i), a(b)
//    {
//
//    }
//};

//int main()
//{
//    T t(100);
//    std::cout << t.a << " " << t.b << std::endl;
//    return 0;
//}


//
//
//第四题
class TestObj 
{
private:
    int mVal = 0;
    char mData[100] = { 0 };
public:
    TestObj() 
    {
        std::cout << "TestObj()" << std::endl;
    }

    TestObj(int val, const char* data = nullptr) : mVal(val) 
    {
        if (data && strlen(data) < 100)
        {
            memcpy(mData, data, strlen(data) + 1);
            std::cout << "TestObj()" << std::endl;
        }
    }
    TestObj(const TestObj& t) : mVal(t.mVal) 
    {
        memcpy(mData, t.mData, 100);
        std::cout << "TestObj(const TestObj& t)" << std::endl;
    }

    int getVal() 
    {
        return mVal;
    }
    char* getData() 
    {
        return mData;
    }
};

//这个函数可以怎么优化。并说出为什么
//TestObj getObject(TestObj t) 
//{
//    int val = t.getVal();
//    val++;
//    TestObj tmp = TestObj(val, t.getData()); // 构造 + 拷贝构造 --> 直接构造tmp对象
//    return tmp; // 拷贝构造一个临时对象，拷贝构造外部对象 --> 拷贝构造外部对象
//    // 最终，是需要一次构造函数，一次拷贝构造函数
//}
// 优化
TestObj getObject(TestObj& t)
{
    int val = t.getVal();
    val++;
    return TestObj(val, t.getData());
    // 直接构造外部对象
}

//int main()
//{
//    TestObj t1;
//    std::cout << std::endl;
//    TestObj t2 = getObject(t1);
//    return 0;
//}

//#include <sstream>
//#include <iostream>
//#include <string>
//#include <vector>
//
//int main()
//{
//    std::vector<std::string> _cookies;
//    std::string cookieLine = "user=abc; sessionid=123; user2=bdc";
//    std::stringstream cookieSs(cookieLine);
//    std::string singleCookie;
//    while (std::getline(cookieSs, singleCookie, ';'))
//    {
//        std::cout << singleCookie << std::endl;
//        //user=abc
//        // sessionid=123  //  这里头部有一个空格
//        // user2=bdc*/
//        // 去除可能存在的前后空格
//        size_t start = singleCookie.find_first_not_of(" ");
//        size_t end = singleCookie.find_last_not_of(" ");
//        if (start != std::string::npos && end != std::string::npos)
//        {
//            singleCookie = singleCookie.substr(start, end - start + 1);
//        }
//        _cookies.emplace_back(singleCookie);
//    }
//
//
//    for (auto& cookie : _cookies)
//    {
//        std::cout << cookie << std::endl;
//
//    }
//    return 0;
//}

//class A
//{
//public:
//    A(int n) { value = n; }
//    A(A other) { value = other.value; }
//
//    void Print() { std::cout << value << std::endl; }
//private:
//    int value;
//};
//
//int main(int argc, char* argv[])
//{
//    A a = 10;
//    A b = a;
//    b.Print();
//
//    return 0;
//}


//class Person
//{
//public:
//    Person(int a, int w)
//        :age(a), weight(w)
//    {}
//
//    int age = 0;
//    int weight = 0;
//};
//
//int main()
//{
//    Person arr[] = { Person(1, 2), Person(3,4) };
//    return 0;
//}

#include <iostream>
#include <vector>

int countRange(const std::vector<int>& nums, int left, int right)
{
    int count = 0;
    for (auto num : nums)
    {
        if (left <= num && num <= right)
            count++; // 计算数组中出现在[left, right]范围的数字个数
    }
    return count;
}

int getDuplication(std::vector<int>& nums)
{
    int left = 1, right = nums.size() - 1;
    while (left <= right)
    {
        int mid = left + ((right - left) >> 1);
        int count = countRange(nums, left, mid);
        if (left == right)
        {
            if (count > 1)
                return left;
            else
                break;
        }
        if (count > (mid - left + 1))
            right = mid;
        else
            left = mid + 1;
    }
}



int main()
{
    std::vector<int> nums = { 2,5,4,3,2,6,1 };
    std::cout << getDuplication(nums) << std::endl;
    return 0;
}